package org.shop.controller;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.File;
import java.io.IOException;

/**
 * 编写 Servlet，实现文件上传
 * <p>
 * 万能键 ：alt + enter
 * <p>
 * 第一：继承 HttpServlet
 * 第二：重写 doXxx 方法
 * 第三：编辑 doXxx 方法，实现具体的业务逻辑功能 - 文件上传
 * 1.开启上传功能 - @MultipartConfig
 * 2.实例化 Part 对象 - 基于 file 表单控件
 * 3.上传文件 - 调用 Part 对象的 write 方法
 * 第四：定义访问路径
 */
@WebServlet("/upload.do")
@MultipartConfig
public class UploadServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");


        // 第一：实例化 Part 对象 - 通过 file 表单控件中，name 属性实例化
        Part part = req.getPart("attach");

        // 第二：合法性验证
        // 1.获取上传文件的大小（字节） - 对上传文件的容量进行合法性处理
        // 1MB = 1024KB = 1024 * 1024 byte
        // x byte = x / 1024 kb = x / 1024 / 1024 MB
        long size = part.getSize();
        long heFaSize = size / 1024 / 1024 ;
        if (heFaSize >= 1) {
            throw new RuntimeException("上传文件最多只能1MB");
        }

        // 2.获取上传文件的文件名和后缀（扩展名） - 对上传文件的类型进行合法性处理
        String header = part.getHeader("Content-Disposition");
        int startIndex = header.indexOf("filename=")+10 ;
        int endIndex = header.length()-1 ;
        String filename = header.substring(startIndex, endIndex);

        String[] arr = filename.split("\\.");

        if("exe".equals(arr[1])) {
            throw new RuntimeException("对不起，不允许上传可执行文件");
        }

        // 第三：文件上传 - 面向对象的思想 - 调用对象的某个方法
        // 获取上下文对象
        ServletContext servletContext = req.getServletContext();
        // 获取当前项目下 /upload 的真实路径（绝对路径） - 从盘符开始
        String realPath = servletContext.getRealPath("/upload/");

        // 动态的创建上传目录 - 不存在创建，存在跳过
        File file = new File(realPath);
        if(!file.exists()) {
            file.mkdir();
        }

        part.write(realPath + filename);
    }
}
